import { useState, useRef, useCallback } from "preact/hooks";
import Logo from "./Logo";
import SearchBar from "./SearchBar";
import Suggestion from "./Suggestion";
import EngineBar from "./EngineBar";
import { addHistory, delHistory, clearHistory } from "../histories";
import { copyText, useLogoVisible } from "../utilities";
import { checkedEngine, engineKeywords, checkEngine } from "../engines";
import { settings, queryStatus } from "../settings";
import { isPortrait, wordSignal, setWord } from "../signals";
import {
  isExternalFavoUrl,
  parseExternalFavoUrl,
  vendorActions,
} from "../Vendor";

const SearchPart = ({ setting }) => {
  const [count, setCount] = useState(0);
  const inputReference = useRef(null);
  const engBarReference = useRef(null);
  const logoReference = useRef(null);
  const visi = useLogoVisible(
    settings.value.searchPart.showEngine ? engBarReference : logoReference,
  );

  const search = (
    jump = false,
    suggest = void 0,
    skipRecord = false,
    newTab = settings.value.searchPart.newTab,
  ) => {
    const keyword = suggest ?? wordSignal.value;
    const opener = newTab
      ? window.open.bind(globalThis)
      : location.assign.bind(location);
    if (keyword !== "") {
      if (jump) {
        opener(keyword);
      } else {
        let eurl = checkedEngine.value.url;
        const flag = engineKeywords.find((key) => eurl.includes(key));
        const encodedKeyword = encodeURIComponent(keyword);
        if (flag) {
          eurl = eurl.replaceAll(flag, encodedKeyword);
        } else {
          eurl += encodedKeyword;
        }
        if (!skipRecord && queryStatus(2, "searchPart", "suggestSources"))
          addHistory(keyword);
        opener(eurl);
      }
      setWord("");
      document.activeElement?.blur();
    }
    return false;
  };

  const focusInput = () => inputReference.current?.focus();

  const onInput = useCallback(
    (value, refresh) => {
      setWord(value);
      if (refresh) setCount(count + 1);
      if (value !== "") focusInput();
    },
    [count],
  );

  const performer = useCallback(
    (fromOrAction, parameter) => {
      const action =
        typeof fromOrAction == "number"
          ? fromOrAction
          : settings.value.actions[fromOrAction];
      if (action >= 20 && vendorActions.length > 0) {
        return (
          vendorActions.find((ao) => ao.id === action)?.call(parameter) ??
          void 0
        );
      }
      switch (action) {
        case 1 /* 打开主页设置 */: {
          setting.current?.showModal();
          break;
        }
        case 2 /* 清空历史 */: {
          clearHistory();
          setCount(count + 1);
          break;
        }
        case 3 /* 删除指定历史 */: {
          delHistory(parameter);
          setCount(count + 1);
          focusInput();
          break;
        }
        case 4 /* 复制内容 */: {
          copyText(parameter);
          break;
        }
        case 5 /* 填入搜索框 */: {
          onInput(parameter, false);
          break;
        }
        case 6 /* 强制访问 */: {
          search(true, parameter, false, false);
          break;
        }
        case 7 /* 强制新窗口访问 */: {
          search(true, parameter, false, true);
          break;
        }
        case 8 /* 清空搜索框 */: {
          onInput("", true);
          break;
        }
        case 9 /* 搜索 */: {
          search(false, parameter);
          break;
        }
        case 10 /* 复制内容 */: {
          copyText(parameter.word);
          break;
        }
        case 11 /* 填入搜索框 */: {
          onInput(parameter.word, false);
          break;
        }
        case 12 /* 复制地址 */: {
          copyText(parseExternalFavoUrl(parameter.url));
          break;
        }
        case 13 /* 当前标签访问 */: {
          location.assign(parseExternalFavoUrl(parameter.url));
          break;
        }
        case 14 /* 新窗口访问 */: {
          isExternalFavoUrl(parameter.url)
            ? window.open(parseExternalFavoUrl(parameter.url))
            : location.assign(parameter.url);
          break;
        }
        case 15 /* 打开书签 */: {
          settings.value.favo.newTab && isExternalFavoUrl(parameter.url)
            ? window.open(parseExternalFavoUrl(parameter.url))
            : location.assign(parameter.url);
          break;
        }
        case 16 /* 访问链接 */: {
          search(true, parameter);
          break;
        }
        case 17 /* 搜索不记录 */: {
          search(false, parameter, true);
          break;
        }
        case 18 /* 上一个引擎 */: {
          checkEngine(false);
          break;
        }
        case 19 /* 下一个引擎 */: {
          checkEngine(true);
          break;
        }
      }
    },
    [setting, onInput, count],
  );

  const onLogoClick = () => performer("logoClick");
  const onLogoPress = () => performer("logoPress");
  const onButtonClick = () => performer("searchClick");
  const onButtonPress = (parameter) => performer("searchPress", parameter);
  const onSuggestPress = (action, parameter) => performer(action, parameter);

  return (
    <>
      <Logo
        ref={logoReference}
        onClick={onLogoClick}
        onContextMenu={onLogoPress}
      />
      <EngineBar ref={engBarReference} focusInput={focusInput} />
      <search
        class={
          visi
            ? "dropdown"
            : `dropdown bg-base-100 sticky z-1 flex h-max max-w-(--screen-w) place-items-center p-2 shadow-md ${isPortrait.value ? "top-[0] w-full" : "top-2 m-auto w-max rounded-(--search-bar-radius)"}`
        }
      >
        {visi ? (
          void 0
        ) : (
          <Logo onClick={onLogoClick} onContextMenu={onLogoPress} slide />
        )}
        <SearchBar
          ref={inputReference}
          search={search}
          onButtonClick={onButtonClick}
          onButtonPress={onButtonPress}
          onSwap={focusInput}
        />
        <Suggestion onInput={onSuggestPress} extCount={count} />
      </search>
    </>
  );
};

export default SearchPart;
